/*
 *  Copyright 2008-2010 www.jrails.org
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.rails.core.model.attribute;

import java.sql.Timestamp;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.rails.core.model.ActiveRecord;
import org.rails.core.util.Utils;

public final class TimestampAttribute extends AttributeBase {

	private Timestamp value;

	public TimestampAttribute(final ActiveRecord record,final String attriubte) {
		super(record, attriubte);
	}

	@Override
	public void validate() throws AttributeException {
		this.value = parse(inputValue);
		if (isEmpty(this.value))
			this.value = getDefaultValue();

		if (require && isEmpty(this.value)) {
			throwAttRequireError();
		}
		checkRange();
		if (unique)
			checkUnique();
	}

	@Override
	public Timestamp getValue() {
		return value;
	}

	@Override
	public boolean isTrim() {
		return false;
	}

	@Override
	public Timestamp getMin() {
		try {
			return parse(get(MIN_KEY));
		} catch (Exception e) {
			logger.error("Config error : " + this.modAtt + ".min = "
					+ get(MIN_KEY));
			return null;
		}
	}

	@Override
	public Timestamp getMax() {
		try {
			return parse(get(MAX_KEY));
		} catch (Exception e) {
			logger.error("Config error : " + this.modAtt + ".max = "
					+ get(MAX_KEY));
			return null;
		}
	}

	@Override
	public Timestamp getDefaultValue() {
		try {
			return parse(get(DEFAULT_KEY));
		} catch (Exception e) {
			logger.error("Config error : " + this.modAtt + ".default = "
					+ get(DEFAULT_KEY));
			return null;
		}
	}

	@Override
	public Timestamp parse(Object arg) throws AttributeException {
		final boolean isFormat = containsKey(FORMAT_KEY);
		if (isEmpty(arg)) {
			return null;
		} else if (arg instanceof Timestamp) {
			return (Timestamp) arg;
		} else if (arg instanceof String && isFormat) {
			try {
				return new Timestamp(new SimpleDateFormat(format).parse(arg.toString().trim()).getTime());
			} catch (ParseException e) {
				throwAttFormatError();
				return null;
			}
		} else {
			throwAttTypeError();
			return null;
		}
	}

	private void checkRange() throws AttributeException {
		if (getMin() != null && !isEmpty(this.value)
				&& value.getTime() < getMin().getTime()) {
			throwAttMinError();
		}
		if (getMax() != null && !isEmpty(this.value)
				&& value.getTime() > getMax().getTime()) {
			throwAttMaxError();
		}
	}

	@Override
	public String format(Object arg) {
		if (Utils.isEmpty(arg)) {
			return "";
		} else {
			return new SimpleDateFormat(format).format(arg);
		}
	}

}
